Dynamic Programming (DP) is an algorithmic technique used to efficiently solve problems with overlapping subproblems and optimal substructure by solving each subproblem once and storing its result to avoid redundant work, using either top-down memoization or bottom-up tabulation.
Dynamic Programming is applied when:
This means that solving the whole problem can be broken into smaller problems, and solving those optimally ensures the entire problem is solved optimally.
This contrasts with divide-and-conquer, where subproblems are mostly independent. In DP, subproblems repeat, making caching/memoization valuable.
Memoization - Top-Down Dynamic Programming
Memoization is an optimization technique used primarily in recursive algorithms, where the results of expensive function calls are cached and reused when the same inputs occur again. This avoid redundant computations by storing solution to subproblems as they are first computed.
function fib(n, memo = {}){
if(n <= 1) return n;
if(memo[n]) return memo[n];
memo[n] = fib(n-1, memo) + fib(n-2, memo);
return memo[n];
}
Characteristics:
Tabulation - Bottom-Up Dynamic Programming
Tabulation is a technique in dynamic programming where the solution is built iteratively from the bottom up by solving all subproblems starting from the smallest and using those solutions to build up to the solution of the original problem.
function fib(n){
if(n <= 1) return n;
const dp = [0, 1];
for(let i = 2; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
Characteristics:
1. Given a non negative integer n. Design an algorithm that compute and return the nth number in the Fibonacci Sequence, where the sequence is defined as:
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | 0 | 100000 | 1 |
Output | 0 | (Very large number) | 1 |
Explanation | Base case F(0) | Requires full computation of 100,000 steps | Another base case F(1) |
2. You are Climbing, it takes n steps to reach the top. Each time you can either climb 1 or 2 steps.
Design an algorithm that returns the total number of distinct ways to reach the top.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | 0 | 45 | 1 |
Output | 1 | 1836311903 | 1 |
Explanation | There’s one way to stay at the bottom (do nothing) | Number of distinct step combinations grows exponentially (Fibonacci sequence) | Only one way to reach the first step (take 1 step) |
3. You are climbing a staircase. Each step has a cost.
You can start from either step 0 or step 1.
From each step, you can move one step up or skip one step (move two steps up).
Your goal is to reach the top of the staircase, which is just beyond the last step (i.e., at index n if there are n steps).
Given an array cost where cost[i] is the cost to step on the i-th stair,
Design an algorithm that computes and returns the minimum cost to reach the top.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | [0, 0, 0, 0] | [999, 999, 999, 999, 999] | [10] or [5, 1] |
Output | 0 | 1998 (choose 0→2→4: 999 + 999) | For [10]: 0; For [5, 1]: 1 |
Explanation | No cost on any step → cost remains 0 | High cost forces optimal skipping (min sum) | Single step: skip it to top or pick minimum |
4. You are given a list of daily tasks, where each task has an associated productivity score. Performing two tasks on consecutive days causes burnout, so you must skip at least one day between any two tasks you perform.
Your goal is to maximize the total productivity score without doing two consecutive tasks. Given an integer array tasks[] of length n, where tasks[i] represents the productivity score on day i,
design an efficient algorithm that returns the maximum total productivity score achievable under these conditions.
The productivity task array is provided in chronological order, where:
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | [5, 0, 0, 5, 0] | [1, 2, 3, 4, 5, 6, 7, 8] | [], [0], [3], [10, 0, 0, 10] |
Output | 10 | 20 (choose 1,3,5,7) | 0, 0, 3, 20 |
Explanation | Select Day 0 and Day 3 (non-consecutive) | Alternate max values from skipping a day | Empty input or minimal values handled safely |
5. You are given an array of integers nums representing a sequence of numbers.
Design an algorithm that returns the length of the Longest Strictly Increasing Subsequences (LIS) in nums.
A subsequence is sequence that can be derived from the array by deleting some or no elements without changing the order of the remaining elements.
The increasing subsequence must be strictly increasing (i.e., each number must be greater than the previous).
The elements do not need to be contiguous in the original array.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | [5, 0, 0, 5, 0] | [5, 4, 3, 2, 1] | [1], [] |
Output | 5 | 1 | 1 or 0 |
Explanation | Entire array is increasing | Only individual elements qualify | Single element or empty |
1. Given n items, each with:
You also have a knapsack that can carry at most W units of weight.
Select a subset of the items such that:
Return the maximum total value achievable under these constraints.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | n : Small (e.g., 3–5 items) w Knapsack Capacity: Just enough to fit all optimal items | n : Large (e.g., 1000+ items) w Knapsack Capacity:Slightly too small to include most valuable items | n : 0 or 1 item w Knapsack Capacity:0 or smaller than smallest item weight |
Output | High (value of all items if total weight ≤ W) | Value from carefully chosen subset (not trivial to pick) | 0 or value of only item that fits |
Explanation | Direct inclusion of all items | Requires full DP to find best combination | Algorithm must handle small input / boundary case |
2. Given an array of positive integers coins representing denominations of currency, and an integer amount reresenting a total.
Design an algorithm that return the minimum number of coins needed to make up that amount using the denominations provided.
You may use an unlimited number of coins for each denomination.
If it is not possible to make up the amount with the given denominations, return -1.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | coins: Includes 1 (greedy always works) amount:0 or matches a single coin exactly | coins:Only large denominations like [7, 11, 17] amount:Not divisible by any combination (e.g., 3 with [2, 4]) | coins:Empty array or no useful coin amount:0 or less than smallest coin |
Output | Few coins needed | -1 (impossible to form) | 0 (for amount = 0), or -1 |
Explanation | Amount can be directly constructed | Many iterations; no solution | Valid base case and failure detection required |
3. Given two strings text1 and text2.
Design an algorithm that compute the length of their longest common subsequence (LCS).
A subsequence of a string is a new string generated from the original string by deleting some characters (without changing the relative order of the remaining characters).
The LCS is the longest sequence that appears as a subsequence in both text1 and text2.
Return the length of this LCS.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | Identical strings ("abc", "abc") | Completely different strings ("abc", "xyz") | One or both strings empty ("") |
Output | Length of full string (3) | 0 | 0 |
Explanation | All characters match in order | No matching characters at all | Empty string has no subsequence |
4. Given two strings word1 and word2.
Design an algorithm that compute the minimum number of operations required to convert word1 to word2.
Operations:
Return the minimum number of operations required.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | Identical strings (e.g., "abc", "abc") | Completely different (e.g., "abc", "xyz") | One or both strings are empty ("", "abc") |
Output | 0 | Equal to length of longer word | Length of non-empty string |
Explanation | No changes needed | All characters must be replaced | Full insertion/deletion required |
5. You are organizing a circular conference schedule, where each time slot is associated with a non-negative integer value representing its potential audience interest or revenue.
Due to logistical or resource constraints, no two consecutive sessions can be scheduled, and because the schedule is circular, the first and last sessions are also considered adjacent.
Design an algorithm to determine the maximum total value that can be obtained by selecting non-consecutive time slots under these constraints.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | [10, 1, 10, 1, 10] | [1, 1, 1, 1, 1] | [], [7], [3, 9] |
Output | 20 | 2 | 0, 7, 9 |
Explanation | Choose slots 0 and 2 (or 2 and 4) | Can only take alternate slots (2 total) | Empty → 0; One slot → take it; Two → max of both |
6. Given an array nums of integers. Design an algorithm that finds a contiguous subarray (one or more elements) that has the maximum possible sum and return the sum.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | [2, 3, 4, 5] | [-4, -2, -7, -3] | [0], [5], [] |
Output | 14 | -2 | 0, 5, (handle empty input) |
Explanation | Whole array is the max sum | Choose the least negative | Single-element or zero, or undefined |
7. Given a grid of size m × n, where m is the number of rows and n is the number of columns. Starting from the top-left corner of the grid, you can move only right or down at each step. Your goal is to reach the bottom-right corner of the grid.
Design an algorithm that computes the total number of unique paths from the top-left to the bottom-right corner of the grid.
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | m = 1, n = 1 | m = 100, n = 100 | m = 1, n = 1000 or vice versa |
Output | 1 | Very large number (e.g., 90548514656103281165404177077484163874504589675413336841320) | 1 |
Explanation | Already at destination. Only one path (no move). | Many possible combinations of right and down moves, requiring combinatorics or optimized DP. | Only one direction available; only one path possible (all right or all down). |
8. Given an array of positive integers.
Design an algorithm that determine whether the array can be partitioned into two subsets such that the sum of the elements in both subsets is equal.
Return True if such a partition exists, otherwise return False.
A subset is any group of elements selected from the array such that:
Parameter\ Case | Best Case | Worst Case | Edge Case |
---|---|---|---|
Parameters | [1, 1] | [1, 2, 3, ..., 100] (or any large set) | [1, 1, 3], [1], [1, 2, 5] |
Output | True | False or True (depends on values) | False |
Explanation | Equal sum subsets are [1] and [1]. | Exhaustive search space; needs optimized DP. | Cannot partition into equal subsets due to size or odd sum. |